/**
 * 
 */
package hu.gbalage.owlforms.internal;

import hu.gbalage.owlforms.OWLFormsManager;

import java.util.HashSet;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.semanticweb.owl.inference.OWLReasoner;
import org.semanticweb.owl.inference.OWLReasonerException;
import org.semanticweb.owl.model.OWLCardinalityRestriction;
import org.semanticweb.owl.model.OWLClass;
import org.semanticweb.owl.model.OWLDescription;
import org.semanticweb.owl.model.OWLOntology;
import org.semanticweb.owl.model.OWLSubClassAxiom;

/**
 * @author Grill Balazs (balage.g@gmail.com)
 *
 */
public class OWLHelper {

	private final OWLReasoner reasoner;
	
	private final Log log;
	
	public OWLHelper(OWLFormsManager manager){
		this.reasoner = manager.getReasoner();
		this.log = manager.getLog();
	}
	
	/**
	 * @param clazz
	 * @return
	 */
	public Set<OWLCardinalityRestriction<?,?>> getProperties(OWLClass clazz){
		Set<OWLCardinalityRestriction<?,?>> result = new HashSet<OWLCardinalityRestriction<?,?>>();
		
		for (OWLClass cls : listSuperClasses(clazz))
		for(OWLSubClassAxiom ax : getSubClassAxiomsForLHS(cls)) {
			OWLDescription supclass = ax.getSuperClass();
			log.debug("Found description is: "+supclass.getClass().getCanonicalName());
			if (supclass instanceof OWLCardinalityRestriction<?,?>){
				log.debug("Found a cardinality restriciton.");
				result.add((OWLCardinalityRestriction<?,?>)supclass);
			}
		}
		
		log.debug("Found "+result.size()+" cardinality restrictions.");
		
		return result;
	}
	
	/**
	 * List all ancestor classes. The resulting set contains the given class also.
	 * @param owlclass
	 * @return
	 */
	public Set<OWLClass> listSuperClasses(OWLClass owlclass){
		HashSet<OWLClass> result = new HashSet<OWLClass>();
		result.add(owlclass);
		
		try{
			Set<Set<OWLClass>> clsss = reasoner.getAncestorClasses(owlclass);
				//reasoner.getSuperClasses(owlclass);
			for (Set<OWLClass> clss : clsss )for(OWLClass cls : clss) result.add(cls);
		}catch(OWLReasonerException e){
			e.printStackTrace();
		}
		
		return result;
	}
	
	/**
	 * getSubClassAxiomsForLHS for all loaded ontologies in the reasoner
	 * @param cls
	 * @return
	 */
	public Set<OWLSubClassAxiom> getSubClassAxiomsForLHS(OWLClass cls){
		Set<OWLSubClassAxiom> result = new HashSet<OWLSubClassAxiom>();
		log.debug("getSubClassAxiomsForLHS for: "+cls.getURI());
		
		for(OWLOntology ont : reasoner.getLoadedOntologies()){
			result.addAll(ont.getSubClassAxiomsForLHS(cls));
		}
		
		log.debug("Found "+result.size()+" axioms.");
		
		return result;
	}
	
}
